package com.mobi.Survey.lib.activities;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ResolveInfo;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast;

import com.mobi.Survey.lib.R;
import com.mobi.Survey.lib.model.AlarmPojo;
import com.mobi.Survey.lib.model.AlarmRepeatPojo;
import com.mobi.Survey.lib.model.Credentials;
import com.mobi.Survey.lib.model.SurveyPojo;
import com.mobi.Survey.lib.model.SurveysJsonParser;
import com.mobi.Survey.lib.model.User;
import com.mobi.Survey.lib.model.User.Image;
import com.mobi.Survey.lib.utils.Device;
import com.mobi.Survey.lib.utils.Helper;

/**
 * 
 * <p>
 * <b>Author:</b> Yahya Arshad
 * <p>
 * <b>Company:</b> Mobi Media Soft
 * <p>
 * <b> Website:</b> www.mobimediasoft.com
 * <p>
 * AbstractScreen.java is parent class for all the activities and contains most
 * generic methods used by child activities
 * 
 */
public abstract class AbstractScreen extends FragmentActivity {

	//protected static boolean adsEnabled = true;

	public static final String KEY_USER_ID = "0x1";

	public static final String KEY_USER_PSW = "0x2";

	public static final String KEY_LAYOUT_NAME = "0x3";

	public static final String KEY_LAYOUT_TYPE = "0x4";

	public static final String KEY_SHOW_ADS = "0x5";

	public static final String KEY_LIST_IMAGE = "0x6";

	public static final String KEY_DETAIL_IMAGE = "0x7";

	public static final String KEY_LIST_IMAGE_SIZE = "0x8";

	public static final String KEY_DETAIL_IMAGE_SIZE = "0x9";
	public static final String KEY_AUTOLOAD = "0x10";
	public static final String KEY_NOTIFICATION = "0x11";

	public static final String KEY_MAP_SCREEN_ID = "0x12";
	
	public static final String KEY_AUTOLOAD_ID = "0x13";

	public static final String SHARED_PREF = "LoginScreen";

	protected View headerImage;
	/**
	 * if true non title will not be render
	 */
	protected boolean hideTitle;
	/**
	 * When EditText is first focus of an activity keyboard is automatically
	 * open with activity launch if child activity assign it true keyboard will
	 * not be shown automatically
	 */
	protected boolean hideKeaboard;

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
//		adsEnabled = getResources().getBoolean(R.bool.ADS_ENABLE);
//		adsEnabled = false;
//		if (hideTitle) {
//			hideDefalutTitle();
//		}

		initLayoutIds();
		final int id = getLayoutId();
		if (id > 0) {
			setContentView(id);
		}
		initUiVars();

		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

	}

	public boolean canCall() {
		try {
			Intent callIntent = new Intent(Intent.ACTION_CALL);
			callIntent.setData(Uri.parse("tel:5551231234"));
			List<ResolveInfo> callAppsList = getPackageManager().queryIntentActivities(callIntent, 0);
			return callAppsList.size() > 0;
		} catch (Exception e) {
			return false;
		}

	}

	public static boolean notification(Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);

		return prefs.getBoolean(KEY_NOTIFICATION, true);

	}

	public static void setNotification(boolean on, Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		prefs.edit().putBoolean(KEY_NOTIFICATION, on).commit();

	}



	public static final void setMapTabId(Context ctx, int id) {

		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		prefs.edit().putInt(KEY_MAP_SCREEN_ID, id).commit();
	}

	public static final int getMapTabId(Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);

		int tabId = prefs.getInt(KEY_MAP_SCREEN_ID, -1);
		return tabId;
	}

	

	public static void setAutoLoadUserId(String userId, Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		prefs.edit().putString(KEY_AUTOLOAD_ID, userId).commit();

	}

	
	public static final String getAutoLoadUserId(Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);

		return prefs.getString(KEY_AUTOLOAD_ID, "");

	}
	
	
	public static void setAutoLoad(boolean load, Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		prefs.edit().putBoolean(KEY_AUTOLOAD, load).commit();

	}

	
	public static final boolean isAutoLoadId(Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);

		return prefs.getBoolean(KEY_AUTOLOAD, false);

	}

	protected String getPasswordFromPreferences() {
		SharedPreferences prefs = this.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);

		String psw = prefs.getString(KEY_USER_PSW, null);
		return psw;
	}

	public static final String getUserIdFromPreferences(Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		String userId = prefs.getString(KEY_USER_ID, "").trim();

		return userId;

	}

	public void openMapByAddress(String address) {
		try {

			Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + address));
			startActivity(intent);
		} catch (Exception e) {
			Toast.makeText(this, Messages.NOTHING_FOUND_TO_COMPLETE_ACTION, Toast.LENGTH_LONG).show();
		}

	}

	/**
	 * 
	 * @param dialNo
	 *            Number to call within application
	 */
	public void makeCall(final String dialNo) {

		if (dialNo == null || dialNo.trim().length() == 0) {
			return;
		}

		final Intent callIntent = new Intent(Intent.ACTION_CALL);

		callIntent.setData(Uri.parse("tel:" + dialNo.trim()));
		startActivity(callIntent);
	}

	/**
	 * 
	 * @param email
	 *            To Email Address
	 * @param subject
	 *            Subject of Email Address
	 */
	public void sendEmail(final String email, final String subject, String body) {
		if (email == null || email.length() == 0) {
			return;
		}
		final Intent emailIntent = new Intent(Intent.ACTION_SEND);

		emailIntent.setType("message/rfc822");

		emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { email });
		emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
		emailIntent.putExtra(Intent.EXTRA_TEXT, body);
		startActivity(Intent.createChooser(emailIntent, "Send Email..."));
	}

	/**
	 * 
	 * @param url
	 *            Url of website to open in Android default browser
	 */
	public void openUrl(String url) {
		if (url == null || url.length() == 0)
			return;
		if (!url.startsWith("http://")) {
			url = "http://" + url.trim();
		}
		final Intent i = new Intent(Intent.ACTION_VIEW);
		i.setData(Uri.parse(url));
		startActivity(i);
	}

	public void setContentView(int resourceId) {
		super.setContentView(resourceId);
	}

	public void showLongToast(final String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
	}

	public void showShortToastOnUiThread(final Context context, final String msg) {
		runOnUiThread(new Runnable() {

			@Override
			public void run() {
				Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();

			}
		});
	}

	/**
	 * 
	 * @param message
	 *            Shows a short Toast with message
	 */
	public void showShortToast(String message) {
		Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
	}

	/**
	 * Show generic aler with message
	 * 
	 * @param message
	 */
	public void showAlert(final String message) {
		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(message).setCancelable(false).setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {

			}
		});

		final AlertDialog alert = builder.create();
		alert.show();
	}

	/**
	 * This abstract method is called in onCreate of AbstractScreen.java you
	 * should initialize all your variable in this method for the sake of clean
	 * code
	 */
	protected abstract void initUiVars();

	/**
	 * 
	 * @return Layout id of Screen this return value is used in onCreate of
	 *         AbstractScreen.java in setContentView(int layoutId) we are using
	 *         this strategy instead of directly assigning layout id via
	 *         R.layout.myId because in future we will be able to handle
	 *         different layouts for different devices easily
	 */
	protected abstract int getLayoutId();

	/**
	 * 
	 * @param to
	 *            Name of class to navigate
	 * 
	 *            <p>
	 *            Calling this method will switch screen to other activity
	 */
	protected void switchScreenTo(final Class<?> switchToScreen) {
		startActivity(new Intent(this, switchToScreen));
	}

	@SuppressWarnings({ "unchecked" })
	protected void switchScreenTo(final Class<?> to, Map<String, Object> extras) {

		final Intent intent = new Intent(this, to);
		for (String extraName : extras.keySet()) {
			Object dataToCarry = extras.get(extraName);

			if (dataToCarry instanceof Integer) {
				intent.putExtra(extraName, ((Integer) dataToCarry).intValue());
			} else if (dataToCarry instanceof Boolean) {

				intent.putExtra(extraName, ((Boolean) dataToCarry).booleanValue());
			} else if (dataToCarry instanceof String) {
				intent.putExtra(extraName, (String) dataToCarry);
			} else if (dataToCarry instanceof Long) {
				intent.putExtra(extraName, (Long) dataToCarry);

			} else if (dataToCarry instanceof Parcelable) {
				intent.putExtra(extraName, (Parcelable) dataToCarry);
			} else if (dataToCarry instanceof ArrayList) {
				intent.putParcelableArrayListExtra(extraName, (ArrayList<? extends Parcelable>) dataToCarry);
			}

		}

		startActivity(intent);
	}

	/**
	 * 
	 * @param to
	 *            Name of class to navigate
	 * @param dataToCarry
	 *            A light weight data to transfer other activity will able to
	 *            receive that data currently you can transfer data of type
	 *            Integer, Long and String
	 */

	protected void switchScreenTo(final Class<?> to, final Integer dataToCarry) {
		final Intent intent = new Intent(this, to);
		if (dataToCarry instanceof Integer) {
			intent.putExtra("data", dataToCarry);
		}

		startActivity(intent);
	}

	protected void switchScreenTo(final Class<?> to, final String dataToCarry) {
		final Intent intent = new Intent(this, to);

		intent.putExtra("data", dataToCarry);
		startActivity(intent);
	}

	protected void switchScreenTo(final Class<?> to, final Long dataToCarry) {
		final Intent intent = new Intent(this, to);
		intent.putExtra("data", dataToCarry);
		startActivity(intent);
	}

	protected void switchScreenTo(final Class<?> to, final Parcelable dataToCarry) {
		final Intent intent = new Intent(this, to);
		intent.putExtra("data", (Parcelable) dataToCarry);
		startActivity(intent);
	}

	protected void switchScreenTo(final Class<?> to, final ArrayList<? extends Parcelable> dataToCarry) {
		final Intent intent = new Intent(this, to);

		intent.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataToCarry);

		startActivity(intent);
	}

	public void onBackPressed() {

		onRelease();
		finish();
		super.onBackPressed();

	};

	/**
	 * if hideTitle is true default title bar will not be render
	 */
	private void hideDefalutTitle() {
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		// Remove notification bar
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
	}

	/**
	 * Any resources child class is using must release them on release will be
	 * call in onDestroy by AbstractScreen.Java
	 */
	protected abstract void onRelease();

	/**
	 * This method is called in onCreate of AbstractScreen.java all layout used
	 * in the application should be assign to LayoutIds.LayoutName for screen
	 * instead of directly assigning R.layout.layoutName we will use this
	 * variable
	 */
	private void initLayoutIds() {
		LayoutIds.SURVEY_LIST = R.layout.survey_list;

		LayoutIds.DETAIL_SCREEN_ALL_CONTROLS = R.layout.survey_detail_all_controls;
		LayoutIds.DETAIL_SCREEN_SINGLE_CONTROL = R.layout.survey_detail_single_control;

		LayoutIds.SURVEY_IFNO_SCREEN = R.layout.survey_info;

		LayoutIds.SPLASH_SCREEN = R.layout.splash_mobile;

		LayoutIds.SURVEY_ANSWERS = R.layout.survey_answers;
		LayoutIds.GRAPH_SCREEN = R.layout.graph;

	}

	/**
	 * 
	 * @param message
	 *            Message to print in Console
	 */
	protected void printMessage(String message) {
		Log.i(this.getClass().getSimpleName(), message);
	}

	/**
	 * 
	 * @param message
	 *            Message to print on Android Log Cat
	 */
	protected void printLogMessage(final String message) {
		Log.d(this.getClass().getName(), message);
	}

	/**
	 * class calling this methods must initialize 'protected headerImage field'
	 * 
	 * @param image
	 * @throws NullPointerException
	 *             if headerImage is not initialize
	 */
	protected void showHeaderImage(final Image image) {

		if (null != image.getBitmap() && !image.getBitmap().isRecycled()) {

			final Drawable d = new BitmapDrawable(getResources(), image.getBitmap());

			final int width = Device.getInstance().getPercentWidth(image.getPercentWidth() / 10f);
			final int height = Device.getInstance().getPercentHeight(image.getPercentHeight() / 10f);

			this.headerImage.setLayoutParams(new LayoutParams(width, height));
			this.headerImage.setBackgroundDrawable(d);
			this.headerImage.setVisibility(View.VISIBLE);
		}
	}

	public void setUserPrefrences() {
		SharedPreferences prefs = this.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);

		prefs.edit().putString(KEY_LAYOUT_NAME, User.getInstance().getLayoutName())
				.putInt(KEY_LAYOUT_TYPE, User.getInstance().getLayoutType())
				.putBoolean(KEY_SHOW_ADS, User.getInstance().isShowAds())
				.putString(KEY_LIST_IMAGE, User.getInstance().getListImage().getUrl())
				.putString(KEY_DETAIL_IMAGE, User.getInstance().getDetailImage().getUrl())
				.putFloat(KEY_LIST_IMAGE_SIZE, User.getInstance().getListImage().getPercentHeight())
				.putFloat(KEY_DETAIL_IMAGE_SIZE, User.getInstance().getDetailImage().getPercentHeight()).commit();

	
	}

	protected void getUserPrefrences() {
		SharedPreferences prefs = this.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		User.getInstance().setLayoutName(prefs.getString(KEY_LAYOUT_NAME, "Survey Form"));

		User.getInstance().setLayoutType(prefs.getInt(KEY_LAYOUT_TYPE, 0));

		String detailImageUrl = prefs.getString(KEY_DETAIL_IMAGE, null);
		String listImageUrl = prefs.getString(KEY_LIST_IMAGE, null);

		float detailImageSize = prefs.getFloat(KEY_DETAIL_IMAGE_SIZE, 1);
		float listImageSize = prefs.getFloat(KEY_LIST_IMAGE_SIZE, 1);

		if (null != detailImageUrl) {
			User.getInstance().setDetailImage(new Image(detailImageUrl, detailImageSize));

		}

		if (null != listImageUrl) {
			User.getInstance().setListImage(new Image(listImageUrl, listImageSize));
		}

		//User.getInstance().setShowAds(true);
		
	}

	public static Credentials saveCredentials(String userId, String password, Context ctx) {
		SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE);
		prefs.edit().putString(KEY_USER_ID, userId).putString(KEY_USER_PSW, password).commit();
		return new Credentials(userId, password);
	}

	public void populateUserBitmaps(boolean downloadIfNotExist) {
		try {
			String imageUrl = User.getInstance().getListImage().getUrl();

			if (null != imageUrl && imageUrl.length() > 0) {

				String outputfile = Helper.getTempFile(Helper.getHashNameFromUrl(imageUrl) + "");
				if (!new File(outputfile).exists() && downloadIfNotExist)
					Helper.downloadFile(imageUrl, outputfile);
				try {

					User.getInstance().getListImage().setBitmap(BitmapFactory.decodeFile(outputfile));
				} catch (Exception e) {

				}
			}

			imageUrl = User.getInstance().getDetailImage().getUrl();
			if (null != imageUrl && imageUrl.length() > 0) {

				String outputfile = Helper.getTempFile(Helper.getHashNameFromUrl(imageUrl) + "");
				if (!new File(outputfile).exists() && downloadIfNotExist)
					Helper.downloadFile(imageUrl, outputfile);
				try {
					User.getInstance().getDetailImage().setBitmap(BitmapFactory.decodeFile(outputfile));
				} catch (Exception e) {

				}

			}
		} catch (IOException e) {
			Log.e(LoginScreen.class.getSimpleName(), "Download Error: " + e.getMessage());
		}
	}

	public void setupAlarms(List<AlarmPojo> alarms) {

		int pendingIntentId = 0;

		for (AlarmPojo alarm : alarms) {
			int size = alarm.getRepeats().size();

			if (size == 0) {

				alarm.setPendingIntentId(pendingIntentId);

				if (!alarm.isWithRespectToCurrentTime())
					alarm.setTriggerTime(alarm.getStart());

				alarm.setRepeatType(0);
				alarm.setRepeat(false);

				Helper.setAlarm(this, alarm);
				pendingIntentId++;

			} else {
				if (alarm.isWithRespectToCurrentTime()) {
					alarm.setPendingIntentId(pendingIntentId);

					alarm.setRepeatType(0);
					alarm.setRepeat(false);

					Helper.setAlarm(this, alarm);
					pendingIntentId++;
				}

				for (int i = 0; i < size; i++) {

					AlarmRepeatPojo repeat = alarm.getRepeats().get(i);

					long currentTime = System.currentTimeMillis();
					long triggerTime = 0;

					if (alarm.getStart() < currentTime) {

						triggerTime = AlarmRepeatPojo.getMilliSecondsUntil(repeat.getRepeatType(), alarm.getStart(), 0);

						if (triggerTime < currentTime) {
							triggerTime = AlarmRepeatPojo.getMilliSecondsUntil(repeat.getRepeatType(),
									alarm.getStart(), 1);
						}

					} else {

						triggerTime = alarm.getStart();

					}

					Log.i("Trigger Time:", new Date(triggerTime).toLocaleString());
					AlarmPojo attributes = new AlarmPojo();
					attributes.setId(alarm.getId());
					attributes.setPendingIntentId(pendingIntentId);
					attributes.setMessage(alarm.getMessage());
					attributes.setTriggerTime(triggerTime);
					attributes.setRepeatType(repeat.getRepeatType());
					attributes.setStart(alarm.getStart());
					attributes.setEnd(alarm.getEnd());
					attributes.setRepeat(true);
					attributes.setImageUrl(alarm.getImageUrl());
					attributes.setAudioUrl(alarm.getAudioUrl());
					attributes.setSurveyId(alarm.getSurveyId());
					attributes.setSequanceNo(alarm.getSequanceNo());
					attributes.setUpperLimit(alarm.getUpperLimit());
					attributes.setLowerLimit(alarm.getLowerLimit());
					attributes.setSurveyId(alarm.getSurveyId());
					attributes.setWithRespectToCurrentTime(false);
					Helper.setAlarm(this, attributes);

					pendingIntentId++;

				}

			}

		}

	}

	protected SurveyPojo downloadSurveyDetail(long formId) throws IOException {

		String surveyDetailUrl = getString(R.string.survey_detail_url, formId);

		InputStream loginResponse = Helper.performGetOperationI(surveyDetailUrl);
		SurveyPojo survey = SurveysJsonParser.getInstance().parseSurveyDetailJson(loginResponse, formId);
		return survey;

	}

 

}
